<!-- 消息框 -->
<template>
	<div class="message">
		<header class="header">
			<div v-if="selectedChat" class="flex items-center">
				<img :src="selectedChat.user.img" alt="" class="w-[35px] h-[35px] rounded-[50%] mr-[10px]" />
				<div>
					<div class="text-[#333333] text-[14px] mb-[6px]">
						{{ selectedChat.user.name }}
					</div>
					<div class="text-[#999999] text-[12px]">ID:{{ selectedChat.id }}</div>
				</div>
			</div>
		</header>
		<div ref="messageWrapper">
			<VirtualList
				v-show="!!message.length"
				ref="vsl"
				class="stream scroll-touch"
				:data-key="'index'"
				:item-class="'stream-item'"
				:data-sources="list"
				:data-component="messageComponent"
				:estimate-size="100"
				:class="{ overflow: overflow }"
				@resized="onItemRendered"
				@totop="onTotop"
			>
				<div v-show="overflow" slot="header" class="stream-header">
					<div v-show="!finished" class="spinner"></div>
					<div v-show="finished" class="finished">暂无更多数据</div>
				</div>
			</VirtualList>
			<div v-show="!message.length" class="empty">
				<div class="wrapper">
					<div class="icon"></div>
					<div class="tips">{{ !selectId ? '请选择会话' : '暂无数据' }}</div>
				</div>
			</div>
		</div>
	</div>
</template>

<script>
import { mapGetters, mapState } from 'vuex';
import 'video.js/dist/video-js.css';
import { getChatRecord } from '@/api/mall/chat';
import { formatDate } from '@/utils';
import VirtualList from 'vue-virtual-scroll-list';
import Item from '../chat/Item';
export default {
	components: {
		VirtualList,
	},
	computed: {
		...mapGetters(['selectedChat', 'emojis', 'selectId', 'messages']),
		...mapState(['user']),
		list() {
			return this.message.map((item, index) => {
				if (item.msgType === 4 && typeof item.content === 'string') {
					item.content = JSON.parse(item.content);
				}
				return {
					...item,
					index: index + 1,
				};
			});
		},
	},
	data() {
		return {
			messageComponent: Item,
			overflow: false,
			finished: false,
			params: {
				pageNum: 0,
				pageSize: 10,
				isFirstPageReady: false,
				isFetching: false,
			},
			message: [],
			pages: 1,
		};
	},
	watch: {
		selectId() {
			this.refreshData();
		},
		messages: {
			handler: function () {
				this.message.push(this.messages[this.messages.length - 1]);
				this.setVirtualListToBottom();
			},
			deep: true,
		},
	},
	methods: {
		refreshData() {
			this.message = [];
			this.params = {
				pageNum: 0,
				pageSize: 10,
				isFirstPageReady: false,
				isFetching: false,
			};
			this.pages = 1;
			this.$nextTick(() => {
				this.requestData();
			});
		},
		refresh() {
			this.setVirtualListToBottom();
		},
		push(data) {
			this.message.push({
				...data,
			});
		},
		batch(data) {
			this.message.concat(
				data.map((item) => ({
					...item,
				}))
			);
		},
		onTotop() {
			if (this.params.isFetching) {
				return;
			}
			this.params.isFetching = true;

			this.requestData();
		},
		onItemRendered() {
			if (!this.$refs.vsl) {
				return;
			}
			if (!this.params.isFirstPageReady && this.$refs.vsl.getSizes() >= this.params.pageSize) {
				this.params.isFirstPageReady = true;
				this.setVirtualListToBottom();
			}
			this.checkOverFlow();
		},
		setVirtualListToBottom() {
			if (this.$refs.vsl) {
				this.$refs.vsl.scrollToBottom();
			}
		},
		setVirtualListToOffset(offset) {
			if (this.$refs.vsl) {
				this.$refs.vsl.scrollToOffset(offset);
			}
		},
		checkOverFlow() {
			const vsl = this.$refs.vsl;
			if (vsl) {
				this.overflow = vsl.getScrollSize() > vsl.getClientSize();
			}
		},
		async requestData() {
			try {
				this.params.pageNum++;
				const newData = await this.ajaxGet();
				this.message = newData.concat(this.message.filter((item) => item) || []).filter((item) => {
					if (item.userId === '0') {
						return true;
					}
					return (+item.userId === +this.selectId && +item.joinUserId === this.user.userId) || (+item.joinUserId === +this.selectId && +item.userId === this.user.userId);
				});
				//定位到当前滚动条
				this.$nextTick(() => {
					//第一页默认进来滚动到底部
					if (this.params.pageNum === 1) {
						this.setVirtualListToBottom();
					} else {
						const vsl = this.$refs.vsl;
						const offset = newData
							.map((item) => item.index)
							.reduce((previousValue, currentSid) => {
								const previousSize = typeof previousValue === 'string' && previousValue !== 0 ? vsl.getSize(previousValue) : previousValue;
								return previousSize + this.$refs.vsl.getSize(currentSid);
							}, 0);
						this.setVirtualListToOffset(offset);
					}
					this.params.isFetching = false;
				});
			} catch (err) {
				console.log(err);
			}
		},
		ajaxGet() {
			return new Promise((resolve) => {
				setTimeout(() => {
					getChatRecord({
						uuid: this.selectId,
						current: this.params.pageNum,
						size: this.params.pageSize,
						time: formatDate(new Date()),
					}).then((res) => {
						if (res.data.records.length === 0) {
							this.finished = true;
							return;
						}
						const records = (res.data && res.data.records) || [];
						const data = records.reverse().map((item, index) => ({
							content: item.msg,
							date: item.sendTime,
							self: item.userId.length < 6,
							msgType: item.msgType,
							joinUserId: item.joinUserId,
							userId: item.userId,
							unreadStatus: item.unreadStatus,
							photo: item.photo || require('@/assets/images/tx_02.jpg'),
							index: index + 1,
						}));
						this.pages = res.data.pages || 1;
						resolve(
							data.map((item) => {
								if (item.msgType === 4 && typeof item.content === 'string') {
									item.content = JSON.parse(item.content);
								}
								return item;
							})
						);
					});
				}, 0);
			});
		},
	},
};
</script>

<style lang="scss" scoped>
.video-js .vjs-icon-placeholder {
	width: 100%;
	height: 100%;
	display: block;
}
ul {
	list-style: none;
}
.message {
	width: 100%;
	flex: 1;
	background: #f2f2f2;
	position: relative;
}

.message .header {
	height: 74px;
	padding: 0 17px;
	background-color: #ffff;
	display: flex;
	align-items: center;
}

.message .message-wrapper {
	height: 574px;
	padding: 10px 15px 0;
	overflow-y: auto;
	position: relative;
	display: flex;
}
.stream,
.empty {
	position: relative;
	width: 100%;
	height: 574px;
	overflow-y: auto;
	display: flex;
	flex-direction: column-reverse;
	&.overflow {
		flex-direction: column;
	}
}
.empty {
	.wrapper {
		position: absolute;
		left: 0;
		top: 0;
		bottom: 0;
		right: 0;
		display: flex;
		justify-content: center;
		align-items: center;
		flex-direction: column;
		color: #bfbfbf;
	}
	.icon {
		width: 70px;
		height: 70px;
		background-size: cover;
		background-image: url("data:image/svg+xml,%3Csvg t='1587779561352' class='icon' viewBox='0 0 1024 1024' version='1.1' xmlns='http://www.w3.org/2000/svg' p-id='1970' width='200' height='200'%3E%3Cpath d='M915.90919 428.28025l40.909735 6.785543 1.77339-10.488889 8.708336-12.93766-103.649662-69.574588-7.776104-5.219885-7.837502-2.918469L552.61093 223.932142l-6.92676-2.579755-6.962575 2.308579-347.57209 115.214045-8.804527 2.14792-5.704932 4.046153L53.550637 432.126858l9.832949 13.854543 4.493338 11.238972 39.739073-16.353456L75.734892 485.09114l96.368838 54.05001 0.107447 199.534476-2.349511 4.28356 2.352581 1.310855 0.001023 2.709715 4.859681 0 281.95872 157.194158 7.696286 4.260024 2.344395 1.277086 2.635013 1.726318 9.41851-3.080152 8.748245-3.419889 388.69979-159.572322 0.031722-9.44307L878.607632 546.373879l92.490507-35.759435L915.90919 428.28025zM561.218982 260.057921l245.843174 91.538833-245.843174 92.115977L561.218982 260.057921zM121.002888 475.127208l40.684608-56.45171 5.983271-8.358365 23.439852-32.558533 262.998903 123.622552L411.290297 637.993552 121.002888 475.127208zM203.051579 726.133985l-0.100284-169.629375 226.371704 126.989229 28.646434-91.38636 0.893346 276.69688L203.051579 726.133985zM473.818399 476.500485 225.704508 359.870184l304.674071-100.980879 0 196.376553L473.818399 476.500485zM847.766207 724.616422 489.771743 871.571379l-0.955768-301.186643 45.281299 109.166305 313.667909-121.215736L847.765183 724.616422zM551.061644 639.889739l-57.241702-137.940652 347.098299-130.082684 83.064834 123.892705L551.061644 639.889739z' p-id='1971' fill='%23bfbfbf'%3E%3C/path%3E%3C/svg%3E");
	}
}
.stream {
	&::-webkit-scrollbar {
		display: none;
	}
	::v-deep {
		.stream-item {
			position: relative;
			.time {
				width: 100%;
				font-size: 12px;
				margin: 7px auto;
				display: flex;
				justify-content: center;
				span {
					display: inline-block;
					padding: 4px 6px;
					color: #fff;
					border-radius: 3px;
					background-color: #dcdcdc;
				}
			}
			.time2 {
				margin: 7px auto;
				width: 100%;
				span {
					padding: 4px 6px;
				}
			}
			.main .avatar {
				float: left;
				margin-left: 15px;
				border-radius: 3px;
				width: 42px;
				height: 42px;
			}
			.main .content {
				display: inline-block;
				margin-left: 10px;
				position: relative;
				padding: 6px 10px;
				max-width: 330px;
				min-height: 36px;
				line-height: 24px;
				box-sizing: border-box;
				font-size: 14px;
				text-align: left;
				word-break: break-all;
				background-color: #fafafa;
				border-radius: 4px;

				&.content-video {
					background: transparent;
					padding: 0;
					cursor: pointer;
					position: relative;

					&::before {
						border: 0;
					}

					img {
						position: absolute;
						display: block;
						width: 30px;
						height: 30px;
						top: 50%;
						left: 50%;
						margin-left: -15px;
						margin-top: -15px;
					}

					video {
						width: 150px;
						//height: 100px;
					}
				}
				&.content-audio {
					//padding: 0;
					padding: 5px;
					//background: transparent;
					//.box{
					//  padding: 10px;
					//  background: #fff;
					//}
					audio {
						height: 40px;
						display: block;
					}
				}
				&.content-img {
					background: transparent;
					padding: 0;
					line-height: normal;

					&::before {
						border: 0;
					}

					.img {
						display: block;
						max-width: 150px;
					}
				}
				&::before {
					content: ' ';
					position: absolute;
					top: 12px;
					right: 100%;
					border: 6px solid transparent;
					border-right-color: #fafafa;
				}
			}
			.self {
				text-align: right;
			}
			.self .avatar {
				float: right;
				margin: 0 15px;
			}
			.self .content {
				background-color: rgba(11, 164, 37, 0.46);
			}
			.self .content:before {
				right: -12px;
				vertical-align: middle;
				border-right-color: transparent;
				border-left-color: rgba(11, 164, 37, 0.46);
			}
		}
	}
}
.scroll-touch {
	-webkit-overflow-scrolling: touch;
}
.stream-header {
	padding: 0.5em;
	.finished {
		font-size: 14px;
		text-align: center;
		color: #bfbfbf;
	}
	.spinner {
		font-size: 10px;
		margin: 0px auto;
		text-indent: -9999em;
		width: 15px;
		height: 15px;
		border-radius: 50%;
		background: #ffffff;
		background: linear-gradient(to right, #ccc 10%, rgba(255, 255, 255, 0) 42%);
		position: relative;
		animation: load3 1.4s infinite linear;
		transform: translateZ(0);
	}
	.spinner:before {
		width: 50%;
		height: 50%;
		background: #ccc;
		border-radius: 100% 0 0 0;
		position: absolute;
		top: 0;
		left: 0;
		content: '';
	}
	.spinner:after {
		background: #ffffff;
		width: 75%;
		height: 75%;
		border-radius: 50%;
		content: '';
		margin: auto;
		position: absolute;
		top: 0;
		left: 0;
		bottom: 0;
		right: 0;
	}
	@-webkit-keyframes load3 {
		0% {
			transform: rotate(0deg);
		}
		100% {
			transform: rotate(360deg);
		}
	}
	@keyframes load3 {
		0% {
			transform: rotate(0deg);
		}
		100% {
			transform: rotate(360deg);
		}
	}
}
</style>
